home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1989 / 07 / murray.lst < prev    next >
File List  |  1989-06-01  |  13KB  |  536 lines

  1. _LINE-OF-BEST-FIT_
  2. by William Murray and Chris Pappas
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. mfit17.obj : mfit17.c mfit17.h
  8. CL /c /Lp /Zp /Od /G2sw /W2 mfit17.c
  9.  
  10. mfit17.res : mfit17.rc mfit17.ico mfit17.h mfit17.ptr
  11. RC -r mfit17
  12.  
  13. mfit17.exe : mfit17.obj mfit17.def mfit17.res
  14. link mfit17, /align:16, NUL, OS2, mfit17
  15. rc mfit17.res
  16.  
  17.  
  18. [LISTING TWO]
  19.  
  20. ;MFIT17.DEF for C Compiling
  21.  
  22. NAME           mfit17
  23. EXPORTS        About
  24. EXPORTS        LineDiaProc
  25. EXPORTS        GraphicProc
  26. PROTMODE
  27. HEAPSIZE       2048
  28. STACKSIZE      9216
  29.  
  30.  
  31. [LISTING THREE]
  32.  
  33. #define ID_RESOURCE 10
  34. #define ID_ABOUT    15
  35. #define ID_OK        20
  36. #define ID_CANCEL   25
  37. #define ID_INPUT    30
  38.  
  39. #define IDM_ABOUT    40
  40. #define IDM_INPUT    45
  41. #define IDM_LINEINPUT 55
  42.  
  43. #define DM_XAXIS 470
  44. #define DM_YAXIS 475
  45. #define DM_TITLE 480
  46. #define DM_X1  485
  47. #define DM_Y1  490
  48.  
  49.  
  50. [LISTING FOUR]
  51.  
  52. #include <os2.h>
  53. #include "mfit17.h"
  54.  
  55. POINTER ID_RESOURCE mfit17.ico
  56. POINTER IDP_POINTER mfit17.ptr
  57.  
  58. MENU                ID_RESOURCE
  59. BEGIN
  60.   SUBMENU "Mouse_Data",IDM_LINEINPUT
  61.   BEGIN
  62.     MENUITEM "About...",    IDM_ABOUT
  63.     MENUITEM "Program Data...", IDM_INPUT
  64.   END
  65. END
  66.  
  67. DLGTEMPLATE            ID_ABOUT
  68. BEGIN
  69.   DIALOG "",ID_ABOUT,50,300,180,80,FS_DLGBORDER
  70.   BEGIN
  71.     CTEXT "Mouse Data Input Program",-1,2,60,176,10
  72.     CTEXT "by William H. Murray & Chris H. Pappas",-1,2,45,
  73.       176,10
  74.     CONTROL "OK",ID_OK,75,10,32,14,WC_BUTTON,BS_PUSHBUTTON
  75.         |BS_DEFAULT|WS_GROUP|WS_TABSTOP|WS_VISIBLE
  76.   END
  77. END
  78.  
  79. DLGTEMPLATE ID_INPUT LOADONCALL MOVEABLE DISCARDABLE
  80. BEGIN
  81.     DIALOG "Mouse Program Information",ID_INPUT,76,247,148,193,
  82.         FS_NOBYTEALIGN|FS_DLGBORDER|WS_VISIBLE|
  83.         WS_CLIPSIBLINGS|WS_SAVEBITS,FCF_TITLEBAR
  84.     BEGIN
  85.     CONTROL "Mouse Program Labels",257,2,92,145,72,WC_STATIC,
  86.         SS_GROUPBOX|WS_GROUP|WS_VISIBLE
  87.     CONTROL "X & Y Maximums",259,2,42,145,42,WC_STATIC,
  88.         SS_GROUPBOX|WS_GROUP|WS_VISIBLE
  89.     CONTROL "Enter Title:",260,5,133,51,8,WC_STATIC,SS_TEXT
  90.         |DT_LEFT|DT_TOP|WS_GROUP|WS_VISIBLE
  91.     CONTROL "     x-axis:",261,5,118,54,8,WC_STATIC,SS_TEXT
  92.         |DT_LEFT|DT_TOP|WS_GROUP|WS_VISIBLE
  93.     CONTROL "     y-axis:",262,5,102,50,8,WC_STATIC,SS_TEXT
  94.         |DT_LEFT|DT_TOP|WS_GROUP|WS_VISIBLE
  95.     CONTROL "Mouse Data Points",DM_TITLE,54,132,89,13,
  96.         WC_ENTRYFIELD,ES_LEFT|ES_AUTOSCROLL|ES_MARGIN
  97.         |WS_TABSTOP|WS_VISIBLE
  98.     CONTROL "x - axis label",DM_XAXIS,54,117,89,13,
  99.         WC_ENTRYFIELD,ES_LEFT|ES_AUTOSCROLL|ES_MARGIN
  100.         |WS_TABSTOP|WS_VISIBLE
  101.     CONTROL "y - axis label",DM_YAXIS,54,101,89,13,
  102.         WC_ENTRYFIELD,ES_LEFT|ES_AUTOSCROLL|ES_MARGIN
  103.         |WS_TABSTOP|WS_VISIBLE
  104.     CONTROL "   x:",273,25,57,20,8,WC_STATIC,SS_TEXT|DT_LEFT|
  105.         DT_TOP|WS_GROUP|WS_VISIBLE
  106.     CONTROL "   y:",283,75,57,20,8,WC_STATIC,SS_TEXT|DT_LEFT|
  107.         DT_TOP|WS_GROUP|WS_VISIBLE
  108.     CONTROL "500",DM_X1,50,57,20,15,WC_ENTRYFIELD,ES_LEFT
  109.         |ES_AUTOSCROLL|ES_MARGIN|WS_TABSTOP|WS_VISIBLE
  110.     CONTROL "400",DM_Y1,100,57,20,15,WC_ENTRYFIELD,ES_LEFT
  111.         |ES_AUTOSCROLL|ES_MARGIN|WS_TABSTOP|WS_VISIBLE
  112.     CONTROL "OK",ID_OK,17,13,24,14,WC_BUTTON,BS_PUSHBUTTON
  113.         |WS_TABSTOP|WS_VISIBLE
  114.     CONTROL "Cancel",ID_CANCEL,101,13,34,14,WC_BUTTON,
  115.         BS_PUSHBUTTON|WS_TABSTOP|WS_VISIBLE
  116.     END
  117. END
  118.  
  119.  
  120. [LISTING FIVE]
  121.  
  122.  
  123. /* Cached-PS Window Platform for PM Graphics       */
  124. /* (c) William H. Murray and Chris H. Pappas, 1989 */
  125.  
  126. #define INCL_PM 
  127.  
  128. #include <os2.h>
  129. #include <stddef.h>
  130. #include <stdio.h>
  131. #include <stdlib.h>
  132. #include <string.h>
  133. #include "mfit17.h"
  134.  
  135. MRESULT EXPENTRY About(HWND,USHORT,MPARAM,MPARAM);
  136. MRESULT EXPENTRY LineDiaProc(HWND,USHORT,MPARAM,MPARAM);
  137. MRESULT EXPENTRY GraphicProc(HWND,USHORT,MPARAM,MPARAM);
  138.  
  139. #define maxpts 100
  140.  
  141. HPS   hps;
  142. HWND  hfrm,hcnt;
  143. QMSG  qmsg;
  144. long  ptxorg[maxpts];
  145. long  ptyorg[maxpts];
  146. long  xaxismax=500;
  147. long  yaxismax=400;
  148. char  title[80]="Mouse Data Points";
  149. char  xstring[80]="x - axis label";
  150. char  ystring[80]="y - axis label";
  151. POINTL mousepos;
  152.  
  153. main () 
  154.   { 
  155.   static CHAR pszClassName[]="FirstClass";
  156.   HAB    hab;
  157.   HMQ    hmq;
  158.   HDC    hdc;
  159.   SIZEL page;
  160.   ULONG flFrameFlags=FCF_SYSMENU|FCF_TITLEBAR|
  161.              FCF_SIZEBORDER|FCF_MINMAX|
  162.              FCF_ICON|FCF_MENU;
  163.   ULONG flFrameStyle=WS_VISIBLE;
  164.  
  165.   hab=WinInitialize(0);
  166.   hmq=WinCreateMsgQueue(hab,0);
  167.   WinRegisterClass(hab,pszClassName,GraphicProc,
  168.            CS_SIZEREDRAW,0);
  169.   hfrm=WinCreateStdWindow(HWND_DESKTOP,flFrameStyle,
  170.             &flFrameFlags,pszClassName,
  171.             "Cached-PS PM Graphics",
  172.             0L,NULL,ID_RESOURCE,&hcnt);
  173.   hdc=WinOpenWindowDC(hcnt);
  174.   hps=GpiCreatePS(hab,hdc,&page,PU_PELS|GPIA_ASSOC);
  175.   WinSetWindowPos(hfrm,NULL,10,10,610,470,SWP_SIZE|
  176.             SWP_MOVE|SWP_SHOW);
  177.   while (WinGetMsg(hab,&qmsg,NULL,0,0))
  178.      WinDispatchMsg(hab,&qmsg);
  179.   WinDestroyWindow(hfrm);
  180.   WinDestroyMsgQueue(hmq);
  181.   WinTerminate(hab);
  182.   return 0;
  183.   } 
  184.  
  185. MRESULT EXPENTRY About(hwnd,messg,parm1,parm2)
  186.   HWND     hwnd;
  187.   USHORT messg;
  188.   MPARAM parm1,parm2;
  189.   {
  190.   switch (messg)
  191.     {
  192.     case WM_COMMAND:
  193.       switch (LOUSHORT(parm1))
  194.     {
  195.     case ID_OK:
  196.       WinDismissDlg(hwnd,TRUE);
  197.       return 0;
  198.     }
  199.     break;
  200.     }
  201.     return (WinDefDlgProc(hwnd,messg,parm1,parm2));
  202.   }
  203.  
  204. MRESULT EXPENTRY LineDiaProc(hwnd,messg,parm1,parm2)
  205.   HWND hwnd;
  206.   USHORT messg;
  207.   MPARAM parm1;
  208.   MPARAM parm2;
  209.   {
  210.   short X1;
  211.   short Y1;
  212.     switch (messg)
  213.       {
  214.       case WM_COMMAND:
  215.     switch (LOUSHORT (parm1))
  216.       {
  217.       case ID_OK:
  218.         WinQueryDlgItemText(hwnd,
  219.                 DM_TITLE,
  220.                 80,
  221.                 title);
  222.         WinQueryDlgItemText(hwnd,
  223.                 DM_XAXIS,
  224.                 80,
  225.                 xstring);
  226.         WinQueryDlgItemText(hwnd,
  227.                 DM_YAXIS,
  228.                 80,
  229.                 ystring);
  230.         WinQueryDlgItemShort(hwnd,
  231.                 DM_X1,
  232.                 &X1,
  233.                 1);
  234.         WinQueryDlgItemShort(hwnd,
  235.                 DM_Y1,
  236.                 &Y1,
  237.                 1);
  238.         xaxismax=(long) X1;
  239.         yaxismax=(long) Y1;
  240.         WinDismissDlg(hwnd,TRUE);
  241.         return 0;
  242.  
  243.       case ID_CANCEL:
  244.         WinDismissDlg(hwnd,TRUE);
  245.         return 0;
  246.       }
  247.       break;
  248.       }
  249.   return WinDefDlgProc (hwnd,messg,parm1,parm2);
  250.   }
  251.  
  252. MRESULT EXPENTRY GraphicProc(hwnd,messg,parm1,parm2)
  253.   HWND        hwnd;
  254.   USHORT    messg;
  255.   MPARAM    parm1,parm2;
  256.   {
  257.   static    LONG    ColorDataInfo[]={CLR_NEUTRAL,
  258.                      RGB_BLACK,
  259.                      CLR_BACKGROUND,
  260.                      RGB_WHITE};
  261.   static    HPOINTER linePtr;
  262.   static    HWND     hmenu;
  263.   HPS        hgpi;
  264.   HDC        hdc;
  265.   POINTL    ptl;
  266.   GRADIENTL gradl;
  267.   RECTL     rcl;
  268.   int        i,alength,blength;
  269.   int        lenxstring,lenystring,lentitle,
  270.         lenmaxxlabel,lenmaxylabel;
  271.   long        ptxmax,ptymax,sumx1,sumy1,sumxy1,
  272.         sumxsqr1,deno1,numa1,numb1,
  273.         sumx2,sumy2,sumxy2,sumxsqr2,
  274.         deno2,numa2,numb2;
  275.   long        ptxscaled[maxpts],ptyscaled[maxpts],maxx;
  276.   char        maxxlabel[4],maxylabel[4],
  277.         astring[10],bstring[10];
  278.   double    a1,b1,a2,b2,y;
  279.   static    int j=0;
  280.   static    int npts=0;
  281.  
  282.   /* Length of various strings */
  283.   lentitle=strlen(title);
  284.   lenxstring=strlen(xstring);
  285.   lenystring=strlen(ystring);
  286.  
  287.   /* Convert maximum x value to a string */
  288.   itoa((int)xaxismax,maxxlabel,10);
  289.   lenmaxxlabel=strlen(maxxlabel);
  290.  
  291.   /* Convert maximum y value to a string */
  292.   itoa((int)yaxismax,maxylabel,10);
  293.   lenmaxylabel=strlen(maxylabel);
  294.  
  295.   /* Scale all x values in original array. */
  296.     for (i=0;i<npts;i++)
  297.     ptxscaled[i]=((ptxorg[i]-100)*xaxismax/400);
  298.  
  299.   /* Scale all y values in original array. */
  300.     for (i=0;i<npts;i++)
  301.     ptyscaled[i]=((ptyorg[i]-100)*yaxismax/300);
  302.  
  303.   /* Calculate values for screen equation */
  304.   sumxsqr1=0;
  305.   sumx1=0;
  306.   sumy1=0;
  307.   sumxy1=0;
  308.   for (i=0;i<npts;i++)
  309.   {
  310.     sumxsqr1+=ptxscaled[i]*ptxscaled[i];
  311.     sumx1+=ptxscaled[i];
  312.     sumy1+=ptyscaled[i];
  313.     sumxy1+=ptxscaled[i]*ptyscaled[i];
  314.   }
  315.   deno1=(npts*sumxsqr1)-(sumx1*sumx1);
  316.   numa1=(sumxsqr1*sumy1)-(sumx1*sumxy1);
  317.   numb1=(npts*sumxy1)-(sumx1*sumy1);
  318.  
  319.   /* Calculate values for drawing line on screen */
  320.   sumxsqr2=0;
  321.   sumx2=0;
  322.   sumy2=0;
  323.   sumxy2=0;
  324.   for (i=0;i<npts;i++)
  325.   {
  326.     sumxsqr2+=ptxorg[i]*ptxorg[i];
  327.     sumx2+=ptxorg[i];
  328.     sumy2+=ptyorg[i];
  329.     sumxy2+=ptxorg[i]*ptyorg[i];
  330.   }
  331.   deno2=(npts*sumxsqr2)-(sumx2*sumx2);
  332.   numa2=(sumxsqr2*sumy2)-(sumx2*sumxy2);
  333.   numb2=(npts*sumxy2)-(sumx2*sumy2);
  334.  
  335.   switch (messg) 
  336.     { 
  337.  
  338.     case WM_CREATE:
  339.       linePtr=WinLoadPointer(HWND_DESKTOP,
  340.                  NULL,IDP_POINTER);
  341.       return 0;
  342.  
  343.     case WM_BUTTON1DOWN:
  344.       GpiSetMarker(hps,MARKSYM_PLUS);
  345.       GpiSetColor(hps,CLR_BLUE);
  346.       mousepos.x=(LONG) LOUSHORT(parm1);
  347.       mousepos.y=(LONG) HIUSHORT(parm1);
  348.       if(mousepos.x>99 & mousepos.x<500 &
  349.      mousepos.y>99 & mousepos.y<400)
  350.      {
  351.      ptxorg[j]=mousepos.x;
  352.      ptyorg[j]=mousepos.y;
  353.      j++;
  354.      npts=j;
  355.      GpiMarker(hps,&mousepos);
  356.      }
  357.       return TRUE;
  358.  
  359.     case WM_MOUSEMOVE:
  360.       WinSetPointer(HWND_DESKTOP,linePtr);
  361.       return 0;
  362.  
  363.     case WM_BUTTON2DOWN:
  364.       GpiSetColor(hps,CLR_RED);
  365.       j=0;            /*reset pointer */
  366.       maxx=0;
  367.       /* Slope and intercept for org. and scaled */
  368.       a1=(double) numa1/deno1;
  369.       b1=(double) numb1/deno1;
  370.       a2=(double) numa2/deno2;
  371.       b2=(double) numb2/deno2;
  372.  
  373.       /* Starting point for line of best fit */
  374.       for (i=99;i<510;i++)
  375.     {
  376.       y=a2+(b2*i);
  377.       if(y>99.0 && y<410.0)
  378.       {
  379.         ptl.x=i;
  380.         ptl.y=(long) y;
  381.         break;
  382.       }
  383.     }
  384.       GpiMove(hps,&ptl);
  385.  
  386.       /* Ending point for line of best fit */
  387.       for (i=510;i>99;i--)
  388.     {
  389.       y=a2+(b2*i);
  390.       if(y>99.0 && y<410.0)
  391.       {
  392.         ptl.x=i;
  393.         ptl.y=(long) y;
  394.         break;
  395.       }
  396.     }
  397.       GpiLine(hps,&ptl);
  398.  
  399.     /* Draw the equation to the screen. */
  400.       GpiSetColor(hps,CLR_WHITE);
  401.       ptl.x=100;
  402.       ptl.y=80;
  403.       GpiMove(hps,&ptl);
  404.       ptl.x=500;
  405.       ptl.y=55;
  406.       GpiBox(hps,DRO_FILL,&ptl,0L,0L);
  407.       GpiSetColor(hps,CLR_RED);
  408.  
  409.       gcvt(a1,7,astring);
  410.       alength=strlen(astring);
  411.       gcvt(b1,7,bstring);
  412.       blength=strlen(bstring);
  413.       ptl.x=300-(LONG)(alength+blength+8)*4;
  414.       ptl.y=62;
  415.       GpiMove(hps,&ptl);
  416.       GpiCharString(hps,4L,"y = ");
  417.       GpiCharString(hps,(long) alength,astring);
  418.       GpiCharString(hps,3L," + ");
  419.       GpiCharString(hps,(long) blength,bstring);
  420.       GpiCharString(hps,3L,"(x)");
  421.       return TRUE;
  422.  
  423.     case WM_SIZE:
  424.       if (hmenu==NULL)
  425.     hmenu=WinWindowFromID(WinQueryWindow(hwnd,
  426.                   QW_PARENT,FALSE),FID_MENU);
  427.       return 0;
  428.  
  429.     case WM_COMMAND:
  430.       {
  431.       switch (COMMANDMSG(&messg)->cmd)
  432.     {
  433.     case IDM_ABOUT:
  434.       if (WinDlgBox(HWND_DESKTOP,hwnd,About,
  435.             NULL,ID_ABOUT,NULL))
  436.          WinInvalidateRect(hwnd,NULL,FALSE);
  437.     return 0;
  438.  
  439.     case IDM_INPUT:
  440.       if (WinDlgBox(HWND_DESKTOP,hwnd,LineDiaProc,
  441.             NULL,ID_INPUT,NULL))
  442.           WinInvalidateRect(hwnd,NULL,FALSE);
  443.       return 0;
  444.  
  445.     return 0;
  446.     }
  447.       }
  448.     break;
  449.  
  450.     case WM_PAINT:
  451.     hgpi=WinBeginPaint(hwnd,NULL,NULL);
  452.     GpiCreateLogColorTable(hgpi,LCOL_RESET,
  453.      LCOLF_INDRGB,0L,4L,ColorDataInfo);
  454.     GpiErase(hgpi);
  455.  
  456. /*--------- your routines below ----------*/
  457.  
  458.     GpiSetColor(hgpi,CLR_BLACK);
  459.  
  460.     /* Draw X and Y coordinate axis */
  461.     ptl.x=99;
  462.     ptl.y=410;
  463.     GpiMove(hgpi,&ptl);
  464.     ptl.y=99;
  465.     GpiLine(hgpi,&ptl);
  466.     ptl.x=510;
  467.     GpiLine(hgpi,&ptl);
  468.  
  469.     /* Draw Y axis tic marks */
  470.     ptl.y=130;
  471.     for (i=0;i<10;i++)
  472.       {
  473.       ptl.x=95;
  474.       GpiMove(hgpi,&ptl);
  475.       ptl.x=99;
  476.       GpiLine(hgpi,&ptl);
  477.       ptl.y+=30;
  478.       }
  479.  
  480.     /* Draw X axis tic marks */
  481.     ptl.x=140;
  482.     for (i=0;i<10;i++)
  483.       {
  484.       ptl.y=99;
  485.       GpiMove(hgpi,&ptl);
  486.       ptl.y=95;
  487.       GpiLine(hgpi,&ptl);
  488.       ptl.x+=40;
  489.       }
  490.  
  491.     GpiSetCharMode(hgpi,CM_MODE3);
  492.  
  493.     /* Center and print line chart title */
  494.     ptl.y=410;
  495.     ptl.x=300-((LONG) (lentitle/2)*6);
  496.     GpiCharStringAt(hgpi,&ptl,(LONG) lentitle,title);
  497.  
  498.     /* Center and print horizontal axis label */
  499.     ptl.y=40;
  500.     ptl.x=300-((LONG) (lenxstring/2)*6);
  501.     GpiCharStringAt(hgpi,&ptl,(LONG) lenxstring,
  502.             xstring);
  503.  
  504.     /* Print horizontal axis maximum value */
  505.     ptl.y=82;
  506.     ptl.x=490;
  507.     GpiCharStringAt(hgpi,&ptl,(long) lenmaxxlabel,
  508.             maxxlabel);
  509.  
  510.     /* Print vertical axis maximum value */
  511.     ptl.y=400;
  512.     ptl.x=70;
  513.     GpiCharStringAt(hgpi,&ptl,(long) lenmaxylabel,
  514.             maxylabel);
  515.  
  516.     /* Center and print vertical axis label */
  517.     ptl.y=240-((LONG) (lenystring/2)*6);
  518.     ptl.x=70;
  519.     gradl.x=0;
  520.     gradl.y=90;
  521.     GpiSetCharAngle(hgpi,&gradl);
  522.     GpiCharStringAt(hgpi,&ptl,(LONG) lenystring,
  523.             ystring);
  524.  
  525.     /*--------- your routines above ----------*/
  526.  
  527.     WinEndPaint(hgpi);
  528.     break;
  529.  
  530.     default:
  531.       return WinDefWindowProc(hwnd,messg,parm1,parm2);
  532.     }
  533.   return 0;
  534.   }
  535.  
  536.